<?php
/**
 * Log Klasse
 * 
 * $Rev: $
 * $Author: $
 * $Date: $
 * $Id: $
 * $URL: $
 * @author Adrian Liechti <info@jahweh.ch>
 * @copyright: 2010-2011 Adrian Liechti, GPL3 and CC3 BY-SA
 */

class log {
	
	private $docPath;
	private $doc;
	private $docLog;
	private $docPage;
	private $xsdPath = 'core/log/log.xsd';
	private $loaded = false;
	private $exceptions	= array();
	private $save = false;
	
	private	static $currentLogVersion	= 1;
	private static $xmlns = array(
		'xmlns'					=> 'http://jahweh.ch', 
		'xmlns:xsi'				=> 'http://www.w3.org/2001/XMLSchema-instance', 
		'xsi:schemaLocation'	=> 'http://jahweh.ch ../plugins/core/log/log.xsd');
	private static $globalLog;
	
	public function __construct(path $docPath = NULL, $load = false) {
		if ($docPath === NULL) {
			$this->docPath	= new file ('/log/'.$this->getCurDocName(), path::$root);
		} else {
			$class = get_class($docPath);
			if ($class === file) {
				$this->docPath	= $docPath;
			} elseif ($class === dir) {
				$this->docPath	= file::getFromDir($this->getCurDocName(), $docPath);
			} else {
				// TODO Was jetzt? ;-)
			}
		}
		
		if ($load === true) $this->load();
	}
	
	public function load () {
		global $pluginLoader, $now;
		
		// XML
		$this->doc = new DOMDocument('1.0', 'utf-8');
		$this->doc->formatOutput = true;
		
		if ($this->docPath->exists()) {
			$this->doc->load($this->docPath);
			$this->docLog =& $this->doc->documentElement;
		} else {
			// Log
			$this->docLog = $this->doc->createElement('log');
			$this->docLog->setAttribute('version', self::$currentLogVersion);
			foreach(self::$xmlns as $var => $val) {
				$this->docLog->setAttribute($var, $val);
			}
			$this->doc->appendChild($this->docLog);
		}
		$this->loaded = true;
	}
	
	public function setToGlobalLog () {
		self::$globalLog =& $this;
	}
	
	public static function addException (&$exception) {
		self::$globalLog->exceptions[] =& $exception;
		self::$globalLog->save = true;
	}
	
	public function save () {
		global $now, $pluginLoader;
		
		if ($this->loaded === false) $this->load();
		
		// Page
		$this->docPage = $this->doc->createElement('page');
		$this->docPage->setAttribute('date', $now->format(DateTime::W3C));
		$this->docLog->appendChild($this->docPage);
		
		// Plugin Register
		$reg =& $t->getRegistred('log', 'addToPage');
		if ($reg !== false) {
			foreach ($reg as $regc) {
				if (is_callable($regc['function'])) {
					/**
					 * TODO Dokumentieren im XSD File
					 */
					try {
						call_user_func_array($regc['function'], array(&$this->docPage, &$this->doc));
					} catch (e $e) {
						/**
						 * Do Nothing
						 */
					}
				}
			}
		}
		
		// Exceptions
		foreach (self::$exceptions as $exception) {
			$this->getXML($exception);
		}
		return $this->doc->save($this->docPath);
	}
	
	public function getXML (&$e) {
		// Exception
		$xmlException = $this->doc->createElement('exception');
		$xmlException->setAttribute('type', $e->type());
		$xmlException->setAttribute('code', $e->code);
		$xmlException->setAttribute('file', $e->file);
		$xmlException->setAttribute('line', $e->line);
		$this->docPage->appendChild($xmlException);
	
		// Vars
		if (count($e->vars) > 0) {
			$xmlVars = $this->doc->createElement('vars');
			$e->fetchVars($xmlVars, $e->vars);
			$xmlException->appendChild($xmlVars);
		}
		
		$xmlMessage = $this->doc->createElement('message', $e->message);
		$xmlException->appendChild($xmlMessage);
	}
	
	protected function fetchVars (&$xmlVars, &$vars) {
		foreach ($vars as $var) {
			$xmlVar		= $this->doc->createElement('var');
			$xmlTitle	= $this->doc->createElement('title', $var['t']);
			$xmlValue	= $this->doc->createElement('value');
			$xmlVar->appendChild($xmlTitle);
			if (is_array($var['v'])) {
				if (isset($var['v']['t'], $var['v']['v'])) {
					$this->fetchVars($this-doc, $xmlValue, $var['v']);
				} else {
					/**
					 * TODO ArrayToXML()
					 */
					$xmlValue->nodeValue = var_export($var['v'], true);
				}
			} else {
				$xmlValue->nodeValue = $var['v'];
			}
		}
	}
	
	public function validate () {
		return $this->doc->schemaValidate(realpath($pluginLoader->dirPlugins.'/'.$this->xsdPath));
	}
	
	private function getCurDocName () {
		global $now;
		return 'log_'.$now->format('Y-m-d').'.xml';
	}
	
	public function destruct () {
		if (self::$save === true) {
			$this->save();
		}
	}
	
	public static function destructAll () {
		
	}
	
}
?>